package com.nulldev.util.graphics.renderIt.api.utils;

import java.util.Queue;
import java.util.concurrent.ArrayBlockingQueue;

import com.nulldev.util.concurrency.threadIt.v4.emapi.ExecutorManager;
import com.nulldev.util.concurrency.threadIt.v4.emapi.uft.Executable;
import com.nulldev.util.graphics.renderIt.api.renderItConstants;
import com.nulldev.util.graphics.renderIt.api.renderItGraphicsInterface;
import com.nulldev.util.graphics.renderIt.renderer.global.rColor;

public class RITViewportUtils {

	public static int getTileWidth(final renderItGraphicsInterface iface) {
		return (int) Math.floor(iface.viewport_getWidth() / 8);
	}

	public static int getTileHeight(final renderItGraphicsInterface iface) {
		return (int) Math.floor(iface.viewport_getHeight() / 8);
	}

	public static void clearCanvas(final renderItGraphicsInterface iface, int x, int y, int width, int height, final rColor color) {
		switch ((int) iface.rit_get(renderItConstants.RIT_GET_SCANOUT_METHOD)) {
			case renderItConstants.RIT_FIXED_TILE_COPY: {
				final int vwidth = iface.viewport_getWidth();
				final int vheight = iface.viewport_getHeight();
				final int tileCount = (int) iface.rit_get(renderItConstants.RIT_GET_TILE_COUNT);
				final int tileX = vwidth / tileCount;
				final int tileY = vheight / tileCount;
				final Queue<Executable<Object>> tiles = new ArrayBlockingQueue<Executable<Object>>(vwidth / tileX);
				ExecutorManager.globalAsyncSubmit(() -> {
					for (int x0 = 0; x0 < vwidth; x0 += tileX) {
						for (int y0 = 0; y0 < vheight; y0 += tileY) {
							final int fx = x0;
							final int fy = y0;
							tiles.offer(ExecutorManager.globalAsyncSubmit(() -> {
								iface.bd_fillRect(fx, fy, tileX, tileY, color);
								return null;
							}));
						}
					}
					return null;
				});
				ExecutorManager.get().awaitQueue(tiles);
				break;
			}
			case renderItConstants.RIT_DYNAMIC_TILE_COPY: {
				final int vwidth = iface.viewport_getWidth();
				final int vheight = iface.viewport_getHeight();
				final int tileX = RITViewportUtils.getTileWidth(iface);
				final int tileY = RITViewportUtils.getTileHeight(iface);
				final Queue<Executable<Object>> tiles = new ArrayBlockingQueue<Executable<Object>>(vwidth / tileX);
				ExecutorManager.globalAsyncSubmit(() -> {
					for (int x0 = 0; x0 < vwidth; x0 += tileX) {
						for (int y0 = 0; y0 < vheight; y0 += tileY) {
							final int fx = x0;
							final int fy = y0;
							tiles.offer(ExecutorManager.globalAsyncSubmit(() -> {
								iface.bd_fillRect(fx, fy, tileX, tileY, color);
								return null;
							}));
						}
					}
					return null;
				});
				ExecutorManager.get().awaitQueue(tiles);
				break;
			}
			case renderItConstants.RIT_DIRECT_SCANOUT:
			default: {
				iface.bd_fillRect(x, y, width, height, color);
				break;
			}
		}
	}

}
